# uncompyle6 version 3.2.3
# Python bytecode 3.6 (3379)
# Decompiled from: Python 3.6.8 |Anaconda custom (64-bit)| (default, Feb 21 2019, 18:30:04) [MSC v.1916 64 bit (AMD64)]
# Embedded file name: site-packages\pytz\lazy.py
from threading import RLock

try:
    from UserDict import DictMixin
except ImportError:
    from collections import Mapping as DictMixin

_fill_lock = RLock()


class LazyDict(DictMixin):
    """Dictionary populated on first use."""

    data = None

    def __getitem__(self, key):
        if self.data is None:
            _fill_lock.acquire()
            try:
                if self.data is None:
                    self._fill()
            finally:
                _fill_lock.release()

        return self.data[key.upper()]

    def __contains__(self, key):
        if self.data is None:
            _fill_lock.acquire()
            try:
                if self.data is None:
                    self._fill()
            finally:
                _fill_lock.release()

        return key in self.data

    def __iter__(self):
        if self.data is None:
            _fill_lock.acquire()
            try:
                if self.data is None:
                    self._fill()
            finally:
                _fill_lock.release()

        return iter(self.data)

    def __len__(self):
        if self.data is None:
            _fill_lock.acquire()
            try:
                if self.data is None:
                    self._fill()
            finally:
                _fill_lock.release()

        return len(self.data)

    def keys(self):
        if self.data is None:
            _fill_lock.acquire()
            try:
                if self.data is None:
                    self._fill()
            finally:
                _fill_lock.release()

        return self.data.keys()


class LazyList(list):
    """List populated on first use."""

    _props = [
        "__str__",
        "__repr__",
        "__unicode__",
        "__hash__",
        "__sizeof__",
        "__cmp__",
        "__lt__",
        "__le__",
        "__eq__",
        "__ne__",
        "__gt__",
        "__ge__",
        "append",
        "count",
        "index",
        "extend",
        "insert",
        "pop",
        "remove",
        "reverse",
        "sort",
        "__add__",
        "__radd__",
        "__iadd__",
        "__mul__",
        "__rmul__",
        "__imul__",
        "__contains__",
        "__len__",
        "__nonzero__",
        "__getitem__",
        "__setitem__",
        "__delitem__",
        "__iter__",
        "__reversed__",
        "__getslice__",
        "__setslice__",
        "__delslice__",
    ]

    def __new__(cls, fill_iter=None):
        if fill_iter is None:
            return list()
        else:

            class LazyList(list):
                pass

            fill_iter = [fill_iter]

            def lazy(name):
                def _lazy(self, *args, **kw):
                    _fill_lock.acquire()
                    try:
                        if len(fill_iter) > 0:
                            list.extend(self, fill_iter.pop())
                            for method_name in cls._props:
                                delattr(LazyList, method_name)

                    finally:
                        _fill_lock.release()

                    return getattr(list, name)(self, *args, **kw)

                return _lazy

            for name in cls._props:
                setattr(LazyList, name, lazy(name))

            new_list = LazyList()
            return new_list


LazyList._props = [prop for prop in LazyList._props if hasattr(list, prop)]


class LazySet(set):
    """Set populated on first use."""

    _props = (
        "__str__",
        "__repr__",
        "__unicode__",
        "__hash__",
        "__sizeof__",
        "__cmp__",
        "__lt__",
        "__le__",
        "__eq__",
        "__ne__",
        "__gt__",
        "__ge__",
        "__contains__",
        "__len__",
        "__nonzero__",
        "__getitem__",
        "__setitem__",
        "__delitem__",
        "__iter__",
        "__sub__",
        "__and__",
        "__xor__",
        "__or__",
        "__rsub__",
        "__rand__",
        "__rxor__",
        "__ror__",
        "__isub__",
        "__iand__",
        "__ixor__",
        "__ior__",
        "add",
        "clear",
        "copy",
        "difference",
        "difference_update",
        "discard",
        "intersection",
        "intersection_update",
        "isdisjoint",
        "issubset",
        "issuperset",
        "pop",
        "remove",
        "symmetric_difference",
        "symmetric_difference_update",
        "union",
        "update",
    )

    def __new__(cls, fill_iter=None):
        if fill_iter is None:
            return set()
        else:

            class LazySet(set):
                pass

            fill_iter = [fill_iter]

            def lazy(name):
                def _lazy(self, *args, **kw):
                    _fill_lock.acquire()
                    try:
                        if len(fill_iter) > 0:
                            for i in fill_iter.pop():
                                set.add(self, i)

                            for method_name in cls._props:
                                delattr(LazySet, method_name)

                    finally:
                        _fill_lock.release()

                    return getattr(set, name)(self, *args, **kw)

                return _lazy

            for name in cls._props:
                setattr(LazySet, name, lazy(name))

            new_set = LazySet()
            return new_set


LazySet._props = [prop for prop in LazySet._props if hasattr(set, prop)]
